<?php 
namespace common\service;

use common\model\sell66\Bot;
use common\model\sell66\UserWithdrawRecord;
use common\model\sell66\User;
use common\model\sell66\UserBalance;
use common\model\sell66\UserBank;
use common\service\UserService;
use common\model\sell66\UserBalanceLog;
use common\model\sell66\BotInv;
use common\model\sell66\UserSteam;
use common\service\QueueService;
use common\libs\StringHelper;
use think\Log;
class WalletService{
    
    public static $instance = null;

    private $withdrawMaxNum = 8; // 每日提现次数

    private $withdrawTotalAmount = 8000; // 每日提现金额
    
    private function __construct(){
    }
    public static function getInstance(){
        if(self::$instance == null){
            self::$instance = new self();
        }
        return self::$instance;
    }
    
    /**
     * 钱包信息
     * @param unknown $userId
     * @return multitype:unknown Ambigous <>
     */
    public function info($userId){
        $balance = UserBalance::getBalanceByUseId($userId);
        $result = array();
        $result['balance'] = $balance['balance'];
        $result['freezeBalance'] = $balance['freeze_balance'];
        return $result;
    }
    
    public function getUserWithdrawRecord($userId,$page,$limit){
        $list = [];
        $count = UserWithdrawRecord::getCountRecord($userId);
        $offset = ($page-1) * $limit;
        $totalPage = ceil($count/$limit);
        $records = UserWithdrawRecord::getUserRecord($userId,$offset,$limit);
        foreach ($records as $record){
            $temp['withdrawNo'] = $record['withdraw_no'];
            $temp['money'] = $record['money'];
            $temp['bankType'] = $record->userbank->bank_type;
            $temp['note'] =  empty($record['note']) ? "" :  $record['note'];
            $temp['money'] =  $record['money'];
            $temp['status'] =  UserWithdrawRecord::$statusText[$record['status']];
            $temp['realName'] =  $record->userbank->real_name;
            $temp['bankName'] = $record->userbank->bank_name;
            $temp['bankAccount'] = $record->userbank->account;
            $temp['updatedTime'] = date('Y-m-d', ($record->updated_time));
            $temp['createdTime'] = date('Y-m-d', ($record->created_time));
            $list[] = $temp;
        }
        return array(
        		'totalPage'=>$totalPage,
        		'currentPage'=>$page,
        		'list'=>$list
        );
    }

    /**
     * 提现申请需要提现密码
     */
    public function applyWithdrawNeedTransPwd($userId, $trans_pwd, $money, $bankType, $account, $realName, $bankId = 0){

        $user = User::getUsersByUserId($userId);

        if(!$user->checkIsSetTransPwd()){
            return -1; //交易密码为空
        }

        if(!$user->checkTransPwd($trans_pwd)){
            return -2; //交易密码不正确
        }

        return $this->applyWithdraw($userId, $money, $bankType, $account, $realName, $bankId);
    }

    /**
     * 提现申请
     */
    public function applyWithdraw($userId,$money, $bankType, $account, $realName, $bankId = 0)
    {
    	$balance = UserBalance::getBalanceByUseId($userId);
        if(!$balance->checkBalance($money, $bankType)){
            return -3; //余额不够
        }
        if ($bankType == 3 && $bankId == 0) {
            return -5; // 未选择银行卡
        }
        $userBankId = UserService::getInstance()->saveUserBank($userId,$bankType,$account,$realName,$bankId);

        if(!$userBankId){
            return -4; //错误
        }

        $result = UserWithdrawRecord::createWithdraw($userId, $userBankId, $money, $balance);

        if(!$result){
            return -4; //错误
        }

        $result['bankType'] = $bankType;
        $result['account'] = $account;
        $result['realName'] = $realName;
        return $result;
    }

    public function defaultWithdrawAccount($userId,$bankType){
        $withdrawType = array('alipay','wechat','bankcard');
        if(!in_array($bankType, $withdrawType)){
            return false;
        }
        $userBank = UserBank::defaultWithdrawAccount($userId,$bankType);
        $result = [];
        if(!empty($userBank)){
            $result['realName'] = $userBank['real_name'];
            $result['account'] = $userBank['account'];
            $result['bankName'] = $userBank['bank_name'];
            $result['bankType'] = $userBank['bank_type'];
        }
        return $result;
    }

	public function getOneByWithdrawNo($userId,$withdrawNo){
		$result = [];
		$record =  UserWithdrawRecord::getOneByWithdrawNo($userId,$withdrawNo);
		if(empty($record)){
			return [];
		}
		$result['withdrawNo'] = $record['withdraw_no'];
		$result['money'] = $record['money'];
		$result['bankType'] = $record->userbank->bank_type;
		$result['money'] =  $record['money'];
		$result['status'] =  $record['status'];
		$result['realName'] =  $record->userbank->real_name;
		$result['bankName'] = $record->userbank->bank_name;
		$result['bankAccount'] = $record->userbank->account;
		$result['updatedTime'] = date('Y-m-d', ($record->updated_time));
		$result['createdTime'] = date('Y-m-d', ($record->created_time));
		return $result;
	}

    /**
     * 获取日期时间
     * @return array
     */
    public function getDayTimeScope()
    {
        $date = date('Y-m-d', time());
        $timestamp = strtotime($date);

        $timeScope = array(
            'lastTime' => strtotime('1 day', $timestamp),
            'startTime' => $timestamp,
        );
        return $timeScope;
    }

    /**
     * 提现审核
     * @param int $userId 用户ID
     * @param int $userBankId 用户账户ID
     * @return bool
     */
    public function withdrawAudit($userId, $userBankId)
    {
        $maxNum = getenv('day_withdraw_max_num');
        $totalAmount = getenv('day_withdraw_total_amount');

        if (!empty($maxNum)) {
           $this->withdrawMaxNum = $maxNum;
        }

        if (!empty($totalAmount)) {
            $this->withdrawTotalAmount = $totalAmount;
        }

        $res1 = $this->withdrawUserAudit($userId);
        if ($res1 == false) {
            return false;
        }

        $res2 = $this->withdrawAccountAudit($userId, $userBankId);
        if ($res2 == false) {
            return false;
        }
        return true;
    }

    /**
     * 提现用户审核
     * @param int $userId 用户ID
     * @return bool
     */
    public function withdrawUserAudit($userId)
    {
        $timeScope = $this->getDayTimeScope();

        $totalNum = UserWithdrawRecord::getWithdrawTotalNum($userId, $timeScope);
        if ($totalNum > $this->withdrawMaxNum) {
            Log::write('The number of users on the day to withdraw the upper limit, user_id:'.$userId);
            return false;
        }

        $amount = UserWithdrawRecord::getWithdrawAmount($userId, $timeScope);
        if ($amount > $this->withdrawTotalAmount) {
            Log::write('The amount of users on the day to withdraw the upper limit, user_id:'.$userId);
            return false;
        }

        return true;
    }

    /**
     * 提现账户审核
     * @param int $userId 用户ID
     * @param int $userBankId 用户账户ID
     * @return bool
     */
    public function withdrawAccountAudit($userId, $userBankId)
    {
        $info = UserBank::getUserBankInfo($userId, $userBankId);
        if (!$info) {
            // query user bank failed
            return false;
        }

        $account = $info->account;
        $userIdInfo = UserBank::getUserIdGroupAccount($account);

        $userIds = array();
        foreach ($userIdInfo as $info) {
            $userIds[] = $info->user_id;
        }

        if (count($userIds) < 2) {
            // query account has unique user 
            return true;
        }

        $timeScope = $this->getDayTimeScope();

        $totalNum = UserWithdrawRecord::getWithdrawTotalNums($userIds, $timeScope);
        if ($totalNum > $this->withdrawMaxNum) {
            Log::write('The number of users on the day to withdraw the upper limit, account:'.$account);
            return false;
        }

        $amount = UserWithdrawRecord::getWithdrawAmounts($userIds, $timeScope);
        if ($amount > $this->withdrawTotalAmount) {
            Log::write('The amount of users on the day to withdraw the upper limit, account:'.$account);
            return false;
        }

        return true;
    }

    public function walletLists($userId, $appId, $page, $limit)
    {
        // 获取该用户钱包地址所有hash, 同步bot_inv
        $hashList = ChainService::getInstance()->assetList($userId);
        $notBelongUser = BotInv::getIssuedBotInvByNotBelongUser($userId, $hashList);    // todo 解绑物品(归属置为0,并记录日志)
        BotInvService::getInstance()->UntieUserInv($userId, $notBelongUser);
        $belongUser = BotInv::getIssuedBotInvByBelongUser($userId, $hashList);          // todo 绑定物品
        BotInvService::getInstance()->bindUserInv($userId, $belongUser);

        $count = BotInv::getBotINVWalletNum($userId, $appId);
        $botInv = BotInv::getBotINVWallet($userId, $appId, $page, $limit);
        if ($botInv) {
            foreach ($botInv as &$inv) {
                $inv = array(
                    'bot_inv_id' => $inv['bot_inv_id'],
                    'app_id' => $inv['app_id'],
                    'market_name' => $inv['market_name'],
                    'market_hash_name' => $inv['market_hash_name'],
                    'asset_hash' => $inv['asset_hash'],
                    'status' => $inv['status'],
                    'status_name' => BotInv::$statusNote[$inv['status']],
                    'selected' => false,
                    'image' => StringHelper::getSteamImageUrl($inv['app_id'], $inv['market_hash_name']),
                );
            }
        }

        return array(
            'games' => InvService::getInstance()->getAppIds($appId),
            'list' => $botInv,
            'totalCount' => $count,
            'totalPage' => ceil($count / $limit),
            'page' => $page,
        );
    }

    public function walletFrom($userId, $appId, array $botInvIds)
    {
        if (count($botInvIds) > 200) {
            return -1;
        }

        $user = User::getUserInfoByUserId($userId);
        if (!$user['wallet_address']) {
            return -4;
        }

        $userInfo = UserSteam::getUserInfo($userId);
        if (!$userInfo) {
            return -2;
        }

        $checkInvs = BotInvService::getInstance()->checkUserInvs($userId, $appId, $botInvIds);
        if (!$checkInvs) {
            return -3;
        }

        foreach ($botInvIds as $botInvId) {
            QueueService::getInstance()->setAdapter('AssetJob')->assetJob($botInvId);
        }
        
        $data = array(
            'user_id' => $userId,
            'bot_inv_id' => $botInvIds,
        );

        return $data;
    }

    public function walletOut($userId, $appId, array $botInvIds)
    {
        if (count($botInvIds) > 200) {
            return -1;
        }

         $user = User::getUserInfoByUserId($userId);
        if (!$user['wallet_address']) {
            return -4;
        }

        $userInfo = UserSteam::getUserInfo($userId);
        if (!$userInfo) {
            return -2;
        }

        $checkInvs = BotInvService::getInstance()->checkWalletInvs($userId, $appId, $botInvIds);
        if (!$checkInvs) {
            return -3;
        }

        QueueService::getInstance()->setAdapter('AssetOutJob')->assetOutJob($userId, $botInvIds);

        $data = array(
            'user_id' => $userId,
            'bot_inv_id' => $botInvIds,
        );

        return $data;
    }
}